package top.zhaoyuliu.logbook.client.appender;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Layout;
import ch.qos.logback.core.UnsynchronizedAppenderBase;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import top.zhaoyuliu.logbook.client.builder.LbBuilder;
import top.zhaoyuliu.logbook.client.compent.AppenderCompent;
import top.zhaoyuliu.logbook.client.link.LinkThreadLocal;
import top.zhaoyuliu.logbook.client.queue.LbQueue;
import top.zhaoyuliu.logbook.client.thread.ThreadPool;
import top.zhaoyuliu.logbook.client.utils.LogObejctUtil;

/**
 * Copyright © 2021 Arain. All rights reserved.
 *
 * @Title: LbLogback.java
 * @Prject: logbook-client
 * @Package: top.zhaoyuliu.logbook.client.appender
 * @Description: <功能详细描述>
 * @author: Arain
 * @date: 2021年1月22日 下午2:09:38
 * @version: V1.0
 */
@Setter
@Getter
@Slf4j
public class LbLogback extends UnsynchronizedAppenderBase<ILoggingEvent> {

	private Layout<ILoggingEvent> layout;

	@Override
	public void start() {
		if (layout == null) {
			addWarn("Layout was not defined");
		}
		log.info("日志上报开始");
		super.start();
	}

	@Override
	public void stop() {
		if (!isStarted()) {
			return;
		}
		log.info("日志上报结束");
		super.stop();
	}

	@Override
	protected void append(ILoggingEvent event) {
		String trackId = LinkThreadLocal.traceID.get();
		ThreadPool.INSTANCE.executor().execute(new Runnable() {
			@Override
			public void run() {
				try {
					if (!check(event)) {
						return;
					}
					LbBuilder lbBuilder = LogObejctUtil.getLogMessage(trackId, event);
					if (ObjectUtil.isNotNull(lbBuilder)) {
						LbQueue.pushLogQueue(lbBuilder);
					}
				} catch (Exception e) {
					e.printStackTrace();
					log.info("日志获取失败");
				}
			}
		});
	}

	private Boolean check(ILoggingEvent event) {
		Boolean flag = true;
		if (event == null || !isStarted()) {
			flag = false;
		}
		if (StrUtil.isBlank(AppenderCompent.getAppId())
				|| ObjectUtil.isNull(AppenderCompent.getClientChannelContext())) {
			flag = false;
		}
		if (CollectionUtil.isNotEmpty(AppenderCompent.getExcludePackages())) {
			for (String pack : AppenderCompent.getExcludePackages()) {
				if (event.getLoggerName().contains(pack)) {
					flag = false;
				}
			}
		}
		return flag;
	}
}
